package com.da.core.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.function.Function;
import java.util.function.UnaryOperator;

public class Utils {
    //    获取resource目录下的文件
    public static File getResourceFile(String fileName) {
        URL resourceURL = Utils.class.getClassLoader().getResource(fileName);
        if (resourceURL != null) {
            return new File(resourceURL.getFile());
        }
        return null;
    }

    //    获取文件的后缀名
    private static String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf(".");
        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
            return fileName.substring(dotIndex + 1).toLowerCase();
        }
        return "";
    }

    //    获取文件名对应的content-type
    private static String getContentTypeByExtension(String fileExtension) {
        switch (fileExtension) {
            case "txt":
                return "text/plain";
            case "html":
            case "htm":
                return "text/html";
            case "css":
                return "text/css";
            case "js":
                return "application/javascript";
            case "json":
                return "application/json";
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "gif":
                return "image/gif";
            case "bmp":
                return "image/bmp";
            case "mp3":
                return "audio/mpeg";
            case "wav":
                return "audio/wav";
            case "mpeg":
                return "video/mpeg";
            case "mp4":
                return "video/mp4";
            case "pdf":
                return "application/pdf";
            case "zip":
                return "application/zip";
            case "doc":
            case "docx":
                return "application/msword";
            case "xls":
            case "xlsx":
                return "application/vnd.ms-excel";
            case "ppt":
            case "pptx":
                return "application/vnd.ms-powerpoint";
            default:
                return "";
        }
    }

    //    获取文件对应的content-type
    public static String getFileContentType(File file) throws FileNotFoundException {
        if (null == file) {
            throw new FileNotFoundException("文件不存在");
        }
        String fileName = file.getName();
        String fileExtension = getFileExtension(fileName);
        return getContentTypeByExtension(fileExtension);
    }

    public static Object convertToFieldType(String value, Class<?> fieldType) {
//        把字符串类型转成类属性对应的类型
        if (fieldType == String.class) {
            return value;
        } else if (fieldType == Integer.class || fieldType == int.class) {
            return Integer.parseInt(value);
        } else if (fieldType == Double.class || fieldType == double.class) {
            return Double.parseDouble(value);
        } else if (fieldType == Boolean.class || fieldType == boolean.class) {
            return Boolean.parseBoolean(value);
        } else if (fieldType == Long.class || fieldType == long.class) {
            return Long.parseLong(value);
        } else if (fieldType == Float.class || fieldType == float.class) {
            return Float.parseFloat(value);
        } else if (fieldType == Short.class || fieldType == short.class) {
            return Short.parseShort(value);
        } else if (fieldType == Byte.class || fieldType == byte.class) {
            return Byte.parseByte(value);
        } else if (fieldType == Character.class || fieldType == char.class) {
            if (value.length() != 1) {
                throw new IllegalArgumentException("Cannot convert string to char: " + value);
            }
            return value.charAt(0);
        } else if (fieldType.isEnum()) {
            @SuppressWarnings({"unchecked", "rawtypes"})
            Enum enumValue = Enum.valueOf((Class<? extends Enum>) fieldType, value);
            return enumValue;
        } else if (fieldType == Date.class) {
            // 这里假设字符串值为日期格式，你可以根据实际情况使用 SimpleDateFormat 解析日期字符串
            // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            // return dateFormat.parse(value);
            throw new UnsupportedOperationException("Date type conversion is not supported in this example");
        }
        throw new IllegalArgumentException("Unsupported field type: " + fieldType.getName());
    }

    public static Map<String, Path> getFilesOnDir(String path) {
        Map<String, Path> result = new HashMap<>();
        try {
            Files.walk(Paths.get(path))
                    .filter(p -> p.toFile().isFile())
                    .forEach(p -> result.put(p.toString(), p));
        } catch (IOException e) {
            throw new RuntimeException("没有找到" + path + "目录");
        }
        return result;
    }

    /**
     * 响应websocket请求
     *
     * @param receiveKey 处理ws连接的 Sec-WebSocket-Key
     * @return 处理后的响应
     */
    public static String getWebSocketAccept(String receiveKey) {
        String keyOrigin = receiveKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        MessageDigest sha1;
        String accept;
        try {
            sha1 = MessageDigest.getInstance("sha1");
            sha1.update(keyOrigin.getBytes());
            accept = new String(Base64.getEncoder().encode(sha1.digest()));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return accept;
    }

    public static void printStartInfo(String mode, int port) throws UnknownHostException {
        System.out.println("[" + mode + "] 开始监听端口: " + port);
        System.out.println("[" + mode + "] http://127.0.0.1:" + port);
        System.out.println("[" + mode + "] http://" + getAddress() + ":" + port);
//        打印banner图,花里胡哨的
        String[] banner = new String[]{
                "    .___                      ___.    ", "  __| _/____    __  _  __ ____\\_ |__  ",
                " / __ |\\__  \\   \\ \\/ \\/ // __ \\| __ \\ ", "/ /_/ | / __ \\_  \\     /\\  ___/| \\_\\ \\",
                "\\____ |(____  /   \\/\\_/  \\___  >___  /", "     \\/     \\/               \\/    \\/"
        };
        // 打印banner图
        for (String s : banner) System.out.println(s);
    }

    public static String getAddress() throws UnknownHostException {
        InetAddress localHost = InetAddress.getLocalHost();
        return localHost.getHostAddress();
    }

    public static String splitStartAndEnd(String source, String start, String end) {
        return source.substring(source.indexOf(start) + 1, source.lastIndexOf(end));
    }

    public static String extractValueFromHeader(String header, String key) {
        String[] lines = header.split("\r\n");
        for (String line : lines) {
            if (line.startsWith(key + "=")) {
                // 从行中提取值，例如 name="example.jpg" => example.jpg
                String valueWithQuotes = line.substring(key.length() + 1);
                return valueWithQuotes.replaceAll("\"", "");
            }
        }
        return null;
    }

    /**
     * 生成 sessionId
     *
     * @return sessionId
     */
    public static String generateSessionId() {
        return Long.toString(System.currentTimeMillis());
    }

    /**
     * 下划线转驼峰式字符串
     *
     * @param str 要转换的字符串
     * @return 转好后的字符串
     */
    @SuppressWarnings("InfiniteLoopStatement")
    public static String underscoreToCamel(String str) {
        UnaryOperator<String> capitalize = s -> s.substring(0, 1).toUpperCase()
                + s.substring(1).toLowerCase();
        Seq<UnaryOperator<String>> seq = c -> {
            c.accept(String::toLowerCase);
            while (true) {
                c.accept(capitalize);
            }
        };
        List<String> list = Arrays.asList(str.split("_"));
        return seq.zip(list, Function::apply).join("");
    }

    /**
     * 一行一行的读取文本文件的内容
     *
     * @param path 文本文件的路径
     * @return 数据流
     */
    public static Seq<String> readLines(Path path) {
        return c -> {
            {
                try (BufferedReader reader = Files.newBufferedReader(path)) {
                    String s;
                    while ((s = reader.readLine()) != null) {
                        c.accept(s);
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }
}
